package org.stars.util;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class FileResourceUtility {

	protected static transient Log log = LogFactory.getLog(FileResourceUtility.class);

	/**
	 * pezzo di regular expression da aggiungere al matcher
	 */
	protected final static String regEx = "([^\\\\]*)";

	/**
	 * Unisce il pattern da applicare al nome della directory e del file e ne
	 * ottiene uno solo.
	 * 
	 * @param sDirPattern
	 *            pattern da applicare al nome delle directory
	 * @param sFilePattern
	 *            pattern da applicare al nome del file
	 * @return pattern da applicare al nome della risorsa
	 */
	protected static String buildFileResourcePattern(String sFilePattern) {
		sFilePattern = StringUtility.nvl(sFilePattern, "*").toLowerCase();
		sFilePattern = StringUtility.replace(sFilePattern, "*", regEx);
		sFilePattern = StringUtility.replace(sFilePattern, ".", "\\.");

		return sFilePattern;
	}

	/**
	 * @param sJarPattern
	 * @param sDirectoryPattern
	 * @param sFilePattern
	 */
	public static void findResources(String baseDir, String sFilePattern) throws Exception {
		findResources(baseDir, sFilePattern, null);
	}

	public static void findResources(String baseDir, String sFilePattern, FileResourceEventHandler resourceHandler) throws Exception {
		if (resourceHandler == null) {
			resourceHandler = new FileDefaultEventHandler();
		}

		sFilePattern = buildFileResourcePattern(sFilePattern);
		Pattern resourcePattern = Pattern.compile(sFilePattern, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
		
		File dir=null;
		
		try {
			dir=new File(baseDir).getAbsoluteFile();
		} catch (Exception e)
		{
			Log log=LogFactory.getLog(FileResourceUtility.class);
			
			log.error("It's impossible to load directory "+baseDir+" Message: "+e.getMessage());
			
			throw(e);
		}
		
		findResourceInternal(dir, resourcePattern, resourceHandler);
	}

	protected static void findResourceInternal(File baseDir, Pattern pattern, FileResourceEventHandler resourceHandler) throws Exception {
		if (baseDir.isFile() || baseDir.list()==null) return;

		int n;
		String fullName, name, path;

		for (File item : baseDir.listFiles()) {
			// log.debug("s = "+item.getAbsolutePath());
			
			// do not consider hidden file
			if (item.isHidden()) continue;

			if (!item.isFile()) {
				findResourceInternal(item, pattern, resourceHandler);
			} else {
				// is a file
				if (pattern.matcher(item.getName()).find()) {
					byte[] buffer;
					InputStream bis = null;
					try {
						buffer = FileUtility.readBytes(item.getAbsolutePath());
						bis = new ByteArrayInputStream(buffer);

						fullName = item.getAbsolutePath();
						n = fullName.lastIndexOf(File.separator)+1;
						path = fullName.substring(0, n);
						name = fullName.substring(n);

						resourceHandler.onFoundResourceEvent(path, name, bis);
					} catch (IOException e) {
						Log log = LogFactory.getLog(FileResourceUtility.class);

						log.error("Error during parsing of file " + item.getName() + ". Error: " + e.getMessage());
					} finally {
						try {
							bis.close();

						} catch (Exception a1) {
							log.error("Errore" + a1.toString());
						}
					}
				}
			}
		}
	}

}
